﻿// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动！任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任！

using Admin.NET.Application.Entity;
using Admin.NET.Application.Service.House.Dto;
using Admin.NET.Core.Service;
using MapsterMapper;
using Microsoft.AspNetCore.Http;
using RazorEngine.Compilation.ImpromptuInterface.InvokeExt;
namespace Admin.NET.Application;

/// <summary>
/// 房屋服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class HouseService : IDynamicApiController, ITransient
{
    /// <summary>
    /// 房屋仓储
    /// </summary>
    private readonly SqlSugarRepository<House> _houseRep;
    /// <summary>
    /// 小区仓储
    /// </summary>
    private readonly SqlSugarRepository<Community> _communityRep;
    /// <summary>
    /// 楼栋仓储
    /// </summary>
    private readonly SqlSugarRepository<Buildings> _buildingsRep;
    /// <summary>
    /// 单元仓储
    /// </summary>
    private readonly SqlSugarRepository<Unit> _unitRep;
    /// <summary>
    /// 楼层仓储
    /// </summary>
    private readonly SqlSugarRepository<Floor> _floorRep;
    /// <summary>
    /// 用户审核管理仓储
    /// </summary>
    private readonly SqlSugarRepository<OccupantAudit> _occupantAuditRep;
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="houseRep">房屋仓储</param>
    /// <param name="_communityRep">小区仓储</param>
    /// <param name="_buildingsRep">楼栋仓储</param>
    /// <param name="floorRep">楼层仓储</param>
    /// <param name="unitRep">单元仓储</param>
    /// /// <param name="_occupantAuditRep">用户审核管理仓储</param>
    public HouseService(SqlSugarRepository<OccupantAudit> _occupantAuditRep,SqlSugarRepository<Floor> floorRep,SqlSugarRepository<Unit> unitRep,SqlSugarRepository<House> houseRep, SqlSugarRepository<Community> _communityRep, SqlSugarRepository<Buildings> _buildingsRep)
    {
        _houseRep = houseRep;
        this._communityRep=_communityRep;
        this._buildingsRep = _buildingsRep;
        _floorRep = floorRep;
        _unitRep = unitRep;
        this._occupantAuditRep = _occupantAuditRep;
    }

    /// <summary>
    /// 分页查询房间
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询房间")]
    public async Task<SqlSugarPagedList<HouseOutput>> Page(PageHouseInput input)
    {
        //房屋-楼层-单元-楼栋-小区
        input.SearchKey = input.SearchKey?.Trim();
        var query = _houseRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.houseName.Contains(input.SearchKey)
            )
            .WhereIF(!string.IsNullOrWhiteSpace(input.houseName), u => u.houseName.Contains(input.houseName.Trim()))
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<Floor>((u, floorid) => u.floorId == floorid.Id)
            .LeftJoin<Unit>((u, floorid, unitId) => floorid.unitId == unitId.Id)
            .LeftJoin<Buildings>((u, floorid, unitId, buildingsid) => unitId.buildingsId == buildingsid.Id)
            .LeftJoin<Community>((u, floorid, unitId, buildingsid, communityid) => buildingsid.communityId == communityid.Id)
            .WhereIF(input.id>0, (u, floorid, unitId, buildingsid, communityid) => buildingsid.Id==input.id)
            .Select((u, floorid, unitId, buildingsid, communityid) => new HouseOutput
            {
                Id = u.Id,
                HouseName = u.houseName,
                floorId = u.floorId,
                floorName = floorid.floorName,
                buildingsId = unitId.buildingsId,
                buildingsName = buildingsid.buildingsName,
                unitId = floorid.unitId,
                unitName = unitId.unitName,
                CommunityId = buildingsid.communityId,
                CommunityName = communityid.CommunityName,
            });
        return await query.ToPagedListAsync(input.Page, input.PageSize);
    }

    /// <summary>
    /// 增加房间
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加房间")]
    public async Task<long> Add(AddHouseInput input)
    {

        var entity = input.Adapt<House>();
        var house = await _houseRep.InsertAsync(entity);

        return entity.Id;
    }

    /// <summary>
    /// 删除房间
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除房间")]
    public async Task Delete(DeleteHouseInput input)
    {
        var entity = await _houseRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _houseRep.FakeDeleteAsync(entity);   //假删除
                                                   //await _houseRep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 更新房间
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新房间")]
    public async Task Update(UpdateHouseInput input)
    {
        var entity = input.Adapt<House>();
        await _houseRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取房间
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取房间")]
    public async Task<HouseByIdOutPut> Detail([FromQuery] QueryByIdHouseInput input)
    {
        var query = await _houseRep.AsQueryable()
            .Where(x => x.Id == input.Id)
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<Floor>((u, floorid) => u.floorId == floorid.Id)
            .LeftJoin<Unit>((u, floorid, unitId) => floorid.unitId == unitId.Id)
            .LeftJoin<Buildings>((u, floorid, unitId, buildingsid) => unitId.buildingsId == buildingsid.Id)
            .LeftJoin<Community>((u, floorid, unitId, buildingsid, communityid) => buildingsid.communityId == communityid.Id)
            .Select((u, floorid, unitId, buildingsid, communityid) => new HouseByIdOutPut
            {
                Id = u.Id,
                HouseName = u.houseName,
                floorId = u.floorId,
                buildingsId = unitId.buildingsId,
                unitId = floorid.unitId,
                CommunityId = buildingsid.communityId,
            }).FirstAsync();
        return query;
    }

    /// <summary>
    /// 获取房间列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取房间列表")]
    public async Task<List<HouseOutput>> List([FromQuery] PageHouseInput input)
    {
        return await _houseRep.AsQueryable().Select<HouseOutput>().ToListAsync();
    }

    /// <summary>
    /// 获取楼层ID列表四级联动
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "FloorfloorIdDropdown"), HttpPost]
    [DisplayName("获取楼层ID列表")]
    public async Task<dynamic> FloorfloorIdDropdown(FloorInputDTO param)
    {
        return await _houseRep.Context.Queryable<Floor>().WhereIF(param.Id > 0, x => x.unitId == param.Id)
                .Select(u => new
                {
                    Label = u.floorName,
                    Value = u.Id
                }
                ).ToListAsync();
    }

    /// <summary>
    /// 获取单元ID列表四级联动 
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "UnitunitIdDropdown"), HttpPost]
    [DisplayName("获取单元ID列表")]
    public async Task<dynamic> UnitunitIdDropdown(FloorInputDTO param)
    {
        return await _houseRep.Context.Queryable<Unit>().WhereIF(param.Id > 0, x => x.buildingsId == param.Id)
                .Select(u => new
                {
                    Label = u.unitName,
                    Value = u.Id
                }
                ).ToListAsync();
    }
    /// <summary>
    /// 获取楼栋ID列表
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "BuildingsbuildingsIdDropdown"), HttpPost]
    [DisplayName("获取楼栋ID列表")]
    public async Task<dynamic> BuildingsbuildingsIdDropdown(FloorInputDTO param)
    {
        return await _houseRep.Context.Queryable<Buildings>().WhereIF(param.Id > 0, x => x.communityId == param.Id)
                .Select(u => new
                {
                    Label = u.buildingsName,
                    Value = u.Id
                }
                ).ToListAsync();
    }
    /// <summary>
    /// 获取小区ID列表
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "CommunityCommunityIdDropdown"), HttpGet]
    [DisplayName("获取小区ID列表")]
    public async Task<dynamic> CommunityCommunityIdDropdown()
    {
        return await _houseRep.Context.Queryable<Community>()
                .Select(u => new
                {
                    Label = u.CommunityName,
                    Value = u.Id
                }
                ).ToListAsync();
    }
    //房屋-楼层-单元-楼栋-小区
    [ApiDescriptionSettings(Name = "GetTree"), HttpGet]
    [DisplayName("获取小区树形")]
    public async Task<List<TreeOutPutDTO>> GetTree()
    {
        //第一步 查找所有小区
        var com =await _communityRep.GetListAsync();
        //第二步 把所有小区循环按照DTO格式塞值
        List<TreeOutPutDTO> tree = new List<TreeOutPutDTO>();
        foreach (var item in com)
        {
            TreeOutPutDTO tree1=new TreeOutPutDTO();
            //通过楼栋的小区Id与循环的小区Id进行相匹配 可能会有很多条 因为对应很多条 塞到DTO
            var bui = _buildingsRep.GetList().Where(x => x.communityId == item.Id);
            tree1.value=item.Id;
            tree1.label=item.CommunityName;
            var config = new TypeAdapterConfig();
            // 其他全局配置...

            var mapper = new Mapper(config);
            //自动映射
            var builur = mapper.From(bui).ForkConfig(x =>
            {
                x.ForType<Buildings, TreeOutPutDTO>().Map(c => c.value, z => z.Id);
                x.ForType<Buildings, TreeOutPutDTO>().Map(c => c.label, z => z.buildingsName);
            }).AdaptToType<List<TreeOutPutDTO>>(); ;
            tree1.Children = builur;
            tree.Add(tree1);
        }
        return tree;
    }
    /// <summary>
    /// 返回所有楼栋信息  房屋-楼层-单元-楼栋-小区
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "GetCard"), HttpGet]
    [DisplayName("获取楼层对应单元")]
    public async Task<List<BuildingsDTO>> GetCard()
    {
        //第一步 把所有楼栋信息给找出来
        var list =await _buildingsRep.GetListAsync();
        List<BuildingsDTO> bui=new List<BuildingsDTO>();
        //第二步 循环楼栋信息表是因为 要查对应楼栋的都有哪些单元
        foreach (var item in list)
        {
            BuildingsDTO buildings = new BuildingsDTO();
            buildings.Id = item.Id;
            buildings.buildingsName=item.buildingsName;
            buildings.buildingsNum = list.Count();
            var unit = _unitRep.AsQueryable();
            buildings.unitNum = unit.Where(x => x.buildingsId == item.Id).Count();
            //循环单元查找对应的楼层
            foreach (var ite in unit.ToList())
            {
                var floor = _floorRep.AsQueryable();
                buildings.floorNum += floor.Where(x => x.unitId == ite.Id).Count();
                
            }
            bui.Add(buildings);
        }
        return bui;
    }
    /// <summary>
    /// 统计所有住户的数量
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "PeopleNum"), HttpGet]
    [DisplayName("统计所有住户的数量")]
    public async Task<int> PeopleNum()
    {
        var num = (from a in await _houseRep.GetListAsync()
                   join b in await _occupantAuditRep.GetListAsync()
                   on a.Id equals b.OccupantAddress
                   select new
                   {
                       a.Id,
                   }).Count();
        return num;
    }
}
